package com.nekonomics
package api.route

import api.dto.request.RequestPaymentReq
import api.dto.response.RspEncoder.*
import domain.service.util.TokenService
import domain.service.{OrderService, PaymentService}
import error.{OrderError, PaymentError, PermissionError}

import com.nekonomics.types.OrderStatus
import zio.*
import zio.http.*
import zio.http.Method.*
import zio.json.*

import java.time.OffsetDateTime


object PayRoute {
  val routes = baseApiPath / "pay" / Routes(
    POST / "notify" -> handler { (req: Request) =>
      for {
        formData <- req.body.asURLEncodedForm
        params = formData.map.map{case (k, v) => k -> v.stringValue.getOrElse("")}
        _ <- ZIO.serviceWithZIO[PaymentService](_.handleAlipayCallback(params))
      } yield Response.text("success")
    },


    POST / "request" -> handler { (req: Request) =>
      for {
        jwt <- extractJwt(req)
        userId <- ZIO.serviceWithZIO[TokenService](_.verifyToken(jwt))
        requestPayment <- extractJsonBody[RequestPaymentReq](req)
        orderId = requestPayment.orderId
        order <- ZIO.serviceWithZIO[OrderService](_.getOrder(orderId))
          .someOrFail(OrderError.OrderNotFound)

        _ <- ZIO.fail(PermissionError.PaymentDenied) when order.userId != userId

        isExpired <- ZIO.serviceWithZIO[OrderService](_.checkIfOrderExpired(orderId))
        _ <- ZIO.fail(OrderError.OrderExpired) when isExpired

        payment <- ZIO.serviceWithZIO[PaymentService](_.getPaymentRecord(orderId))
          .someOrFail(PaymentError.PaymentNotFound)
        resp = payment.htmlForm.toRsp.toJson
      } yield Response.json(resp)
    }

  )


}
